#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "ESP8266.h"
#include "FreeRTOS.h"
#include "cmsis_os.h"
#include "dma.h"
#include "gpio.h"
#include "main.h"
#include "message.h"
#include "stm32f1xx_hal.h"
#include "task.h"

int rx_index = 0;
char rx_buffer[MAX_RX_BUF_SIZE] = {0};
static char send_AT_buffer[MAX_TX_BUF_SIZE] = {0};
static char send_CMD_buffer[MAX_TX_BUF_SIZE] = {0};
static char send_MQTT_buffer[MAX_TX_BUF_SIZE] = {0};

const char *mqttClientId = MQTT_CLIENT_ID;
const char *mqttUsername = MQTT_USERNAME;
const char *mqttPassword = MQTT_PASSWORD;

static void AT_send_cmd(const char *format, ...)
{
    memset(send_AT_buffer, 0, sizeof(send_AT_buffer));
    va_list args;
    va_start(args, format);
    vsnprintf(send_AT_buffer, MAX_TX_BUF_SIZE, format, args);
    va_end(args);
    HAL_UART_Transmit(&USART, (uint8_t *)send_AT_buffer, strlen(send_AT_buffer), HAL_MAX_DELAY);
}

// extern SemaphoreHandle_t xUartRxSemaphore;
// volatile uint8_t semaphoreReleased = 0;

bool ESP8266_Cmd(char *cmd, uint32_t waittime, ...)
{
    va_list args;
    char *reply;
    bool result = false;
    rx_index = 0;
    HAL_UARTEx_ReceiveToIdle_DMA(&USART, (uint8_t *)rx_buffer, MAX_RX_BUF_SIZE);
    AT_send_cmd("%s\r\n", cmd);
    osDelay(waittime);
    rx_buffer[rx_index] = '\0';
    HAL_UART_DMAStop(&USART);
    va_start(args, waittime);
    reply = va_arg(args, char *);
    if (reply == NULL)
    {
        va_end(args);
        return true;
    }
    do
    {
        if (strstr((const char *)rx_buffer, reply))
        {
            result = true;
            break;
        }
    } while ((reply = va_arg(args, char *)) != NULL);
    va_end(args);
    return result;
}

bool ESP8266_Init(void)
{
    LOG("\r\n=== ESP8266 Initialization Started ===\r\n");
    uint8_t step = 1;

    // 步骤1: 重置模块并等待就绪
    LOG("[%d] Sending AT+RST...\r\n", step++);
    while (!ESP8266_Cmd("AT+RST", 2000, "ready", "OK", NULL)) {
        LOG("[%d] Error: AT+RST failed, retrying...\r\n", step-1);
    }
    LOG("[%d] Module reset successful\r\n", step-1);

    // 步骤2: 启用命令回显
    LOG("[%d] Sending ATE1 (Enable Echo)...\r\n", step++);
    while (!ESP8266_Cmd("ATE1", 200, "OK", NULL)) {
        LOG("[%d] Error: ATE1 failed, retrying...\r\n", step-1);
    }
    LOG("[%d] Echo enabled\r\n", step-1);

    // 步骤3: 设置WiFi模式为STA
    LOG("[%d] Sending AT+CWMODE=1 (STA Mode)...\r\n", step++);
    while (!ESP8266_Cmd("AT+CWMODE=1", 800, "OK", NULL)) {
        LOG("[%d] Error: AT+CWMODE=1 failed, retrying...\r\n", step-1);
    }
    LOG("[%d] WiFi mode set to STA\r\n", step-1);

    // 步骤4: 连接WiFi
    sprintf(send_CMD_buffer, "AT+CWJAP=\"%s\",\"%s\"", WiFi_Name, WiFi_PassWord);
    LOG("[%d] Connecting to WiFi: %s...\r\n", step++, WiFi_Name);
    while (!ESP8266_Cmd(send_CMD_buffer, 3000, "OK", NULL)) {
        LOG("[%d] Error: WiFi connection failed, retrying...\r\n", step-1);
    }
    LOG("[%d] WiFi connected successfully\r\n", step-1);

    // 步骤5: 配置MQTT用户
    sprintf(send_CMD_buffer, "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"", mqttClientId, mqttUsername, mqttPassword);
    LOG("[%d] Configuring MQTT user: %s...\r\n", step++, mqttClientId);
    while (!ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL)) {
        LOG("[%d] Error: MQTT user config failed, retrying...\r\n", step-1);
    }
    LOG("[%d] MQTT user configured\r\n", step-1);

    // 步骤6: 连接MQTT服务器
    sprintf(send_CMD_buffer, "AT+MQTTCONN=0,\"%s\",%d,1", MQTT_URL, MQTT_PORT);
    LOG("[%d] Connecting to MQTT server: %s:%d...\r\n", step++, MQTT_URL, MQTT_PORT);
    while (!ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL)) {
        LOG("[%d] Error: MQTT connection failed, retrying...\r\n", step-1);
    }
    LOG("[%d] MQTT server connected\r\n", step-1);

    // 步骤7: 订阅MQTT主题
    sprintf(send_CMD_buffer, "AT+MQTTSUB=0,\"%s\",1", SUBSCRIBE_TOPIC);
    LOG("[%d] Subscribing to topic: %s...\r\n", step++, SUBSCRIBE_TOPIC);
    while (!ESP8266_Cmd(send_CMD_buffer, 1000, "OK", NULL)) {
        LOG("[%d] Error: MQTT subscription failed, retrying...\r\n", step-1);
    }
    LOG("[%d] MQTT topic subscribed\r\n", step-1);

    LOG("=== ESP8266 Initialization Completed ===\r\n");
    return true;
}


bool MQTT_Publish(const char *message)
{
    memset(send_MQTT_buffer, 0, MAX_TX_BUF_SIZE);
    int ret = sprintf(send_MQTT_buffer, "AT+MQTTPUBRAW=0,\"%s\",%d,0,0", PUBLISH_TOPIC, strlen(message));
    if (ret < 0 || ret >= sizeof(send_MQTT_buffer)) return false;
    if (!ESP8266_Cmd(send_MQTT_buffer, 200, "OK", NULL)) return false;
    if (!ESP8266_Cmd((char *)message, 500, "+MQTTPUB:OK", NULL)) return false;
    return true;
}

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart == &USART)
    {
        // if (strncmp((const char *)&rx_buffer[rx_index], "+MQTTSUBRECV:",
        // strlen("+MQTTSUBRECV:")) == 0)
        // {
        //   open_window();
        // }
        // MessageKeyValue pair = {0};
        // if (parse_mqtt_message(&rx_buffer[rx_index], &pair))
        // {
        //   handle_message(&pair);
        // }
        rx_index = Size;
    }
}
